using System;
using System.Runtime.ConstrainedExecution;
using System.Runtime.InteropServices;
using System.Security.Permissions;
using System.Text;

namespace InfiniTec.Security
{
    static class NativeMethods
    {
        [SecurityPermission(SecurityAction.Demand, UnmanagedCode = true)]
        [ReliabilityContract(Consistency.WillNotCorruptState, Cer.MayFail)]
        [DllImport("advapi32.dll", SetLastError = true, CharSet = CharSet.Unicode)]
        [return: MarshalAs(UnmanagedType.Bool)]
        public static extern bool LookupAccountSid(
            [In] string systemName,
            [In, MarshalAs(UnmanagedType.LPArray)] byte[] sid,
            [Out] StringBuilder name,
            [In, Out] ref uint nameLength,
            [Out] StringBuilder referencedDomainName,
            [In, Out] ref uint referencedDomainNameLength,
            [Out] out AccountType usage);

        [SecurityPermission(SecurityAction.Demand, UnmanagedCode = true)]
        [ReliabilityContract(Consistency.WillNotCorruptState, Cer.MayFail)]
        [DllImport("advapi32.dll", SetLastError = true, CharSet = CharSet.Unicode)]
        [return: MarshalAs(UnmanagedType.Bool)]
        public static extern bool LookupAccountName(
            [In] string systemName,
            [In] string accountName,
            [Out, MarshalAs(UnmanagedType.LPArray)] byte[] sid,
            [In, Out] ref uint sidSize,
            [Out] StringBuilder referencedDomainName,
            [In, Out] ref uint referencedDomainNameLength,
            [Out] out AccountType accountType);


        [SecurityPermission(SecurityAction.Demand, UnmanagedCode = true)]
        [ReliabilityContract(Consistency.WillNotCorruptState, Cer.MayFail)]
        [DllImport("advapi32.dll", SetLastError = true)]
        [return: MarshalAs(UnmanagedType.Bool)]
        public static extern bool LookupPrivilegeDisplayName(
            [In] string systemName,
            [In] string privilegeName,
            [In] StringBuilder displayName,
            [In, Out] ref uint displayNameLength,
            out uint languageId);
    

     
        [SecurityPermission(SecurityAction.Demand, UnmanagedCode = true)]
        [ReliabilityContract(Consistency.WillNotCorruptState, Cer.MayFail)]
        [DllImport("advapi32.dll", SetLastError = true, CharSet = CharSet.Unicode)]
        [return: MarshalAs(UnmanagedType.Bool)]
        public static extern bool LogonUser(
            string lpszUsername,
            string lpszDomain,
            IntPtr lpszPassword,
            LogonType dwLogonType,
            LogonProvider dwLogonProvider,
            out UserToken phToken
            );

        [SecurityPermission(SecurityAction.Demand, UnmanagedCode = true)]
        [ReliabilityContract(Consistency.WillNotCorruptState, Cer.MayFail)]
        [DllImport("kernel32.dll", CharSet = CharSet.Auto)]
        [return: MarshalAs(UnmanagedType.Bool)]
        public extern static bool CloseHandle(
            [In] IntPtr handle);

        [ReliabilityContract(Consistency.WillNotCorruptState, Cer.MayFail)]
        [SecurityPermission(SecurityAction.Demand, UnmanagedCode = true)]
        [DllImport("credui.dll", EntryPoint = "CredUIConfirmCredentialsW", CharSet = CharSet.Unicode)]
        public static extern QueryCredentialError CredUIConfirmCredentials(
            [In] string targetName, 
            [In, MarshalAs(UnmanagedType.Bool)] bool confirm);

        [ReliabilityContract(Consistency.WillNotCorruptState, Cer.MayFail)]
        [SecurityPermission(SecurityAction.Demand, UnmanagedCode = true)]
        [DllImport("advapi32.dll", CharSet = CharSet.Unicode, SetLastError = true)]
        public static extern bool AdjustTokenPrivileges([In] IntPtr userToken, 
            [In, MarshalAs(UnmanagedType.Bool)] bool disableAllPrivileges, 
            [In] SafeTokenPrivileges newState, 
            [In] uint bufferLength, [In, Out] IntPtr previousState, 
            [In, Out] ref uint returnLength);

        [DllImport("advapi32.dll", CharSet = CharSet.Auto, SetLastError = true)]
        [ReliabilityContract(Consistency.WillNotCorruptState, Cer.MayFail)]
        [SecurityPermission(SecurityAction.Demand, UnmanagedCode = true)]
        [return: MarshalAs(UnmanagedType.Bool)]
        public static extern bool GetTokenInformation([In] IntPtr tokenHandle, 
            [In] TokenInformationClass tokenInformationClass, 
            [In] SafeTokenPrivileges tokenInformation, 
            [In] uint tokenInformationLength, out uint returnLength);

        [SecurityPermission(SecurityAction.Demand, UnmanagedCode = true)]
        [ReliabilityContract(Consistency.WillNotCorruptState, Cer.MayFail)]
        [DllImport("advapi32.dll", SetLastError = true)]
        [return: MarshalAs(UnmanagedType.Bool)]
        public static extern bool LookupPrivilegeName(string systemName, ref LUID luid,
            StringBuilder privilegeName, ref uint privilegeNameLength);

    }

    /// <summary>
    /// The available logon provider.
    /// </summary>
    public enum LogonProvider
    {
        /// <summary>
        /// Use the standard logon provider for the system. The default security provider 
        /// is negotiate, unless you pass NULL for the domain name and the user name 
        /// is not in UPN format. In this case, the default provider is NTLM. 
        /// </summary>
        /// <remarks>Windows 2000/NT: The default security provider is NTLM.</remarks>
        Default = 0,
        /// <summary>
        /// Use the Windows NT 3.5 logon provider
        /// </summary>
        WinNT35 = 1,
        /// <summary>
        /// Use the NTLM logon provider
        /// </summary>
        WinNT40 = 2,
        /// <summary>
        /// Use the negotiate logon provider.
        /// </summary>
        WinNT50 = 3
    }

    [StructLayout(LayoutKind.Sequential)]
    internal struct LUID
    {
        public uint LowPart;
        public uint HighPart;
    }

    [StructLayout(LayoutKind.Sequential)]
    internal struct LUID_AND_ATTRIBUTES
    {
        public LUID Luid;
        public uint Attributes;
    }

    [StructLayout(LayoutKind.Sequential)]
    internal struct TOKEN_PRIVILEGES
    {
        public uint PrivilegeCount;
        public LUID_AND_ATTRIBUTES[] Privileges;
    }

    static class UnsafeNativeMethods
    {
        [SecurityPermission(SecurityAction.Demand, UnmanagedCode = true)]
        [DllImport("credui", EntryPoint = "CredUIPromptForCredentialsW", CharSet = CharSet.Unicode)]
        public static extern unsafe QueryCredentialError CredUIPromptForCredentials(ref CREDUI_INFO creditUR,
                  [In] string targetName,
                  [In] IntPtr reserved1,
                  [In] int iError,
                  [In, Out] StringBuilder userName,
                  [In] int maxUserName,
                  [In, Out] char* password,
                  [In] int maxPassword,
                  [In, Out, MarshalAs(UnmanagedType.Bool)] ref bool iSave,
                  QueryCredentialOptions flags);


        [SecurityPermission(SecurityAction.Demand, UnmanagedCode = true)]
        [DllImport("credui.dll", EntryPoint = "CredUICmdLinePromptForCredentialsW", CharSet = CharSet.Unicode)]
        public static extern unsafe QueryCredentialError CredUICmdLinePromptForCredentials(
            [In] string targetName,
            [In] IntPtr reserved,
            [In] int authError,
            [In, Out] StringBuilder userName,
            [In] int usernNameBufferSize,
            [In, Out] char* password,
            [In] int passwordBufferSize,
            [In, Out, MarshalAs(UnmanagedType.Bool)] ref bool saveCredential,
            [In] QueryCredentialOptions flags);

    }
    struct CREDUI_INFO
    {
        public int cbSize;
        public IntPtr hwndParent;
        [MarshalAs(UnmanagedType.LPWStr)]
        public string pszMessageText;
        [MarshalAs(UnmanagedType.LPWStr)]
        public string pszCaptionText;
        public IntPtr hbmBanner;
    }

	internal enum WindowsStatusCode
	{
		Success = 0,
		NoMappingPerformed = 1332
	}

    
}
